/*
Archivo de entrada para el antlr que genera el analizador sintáctico.
Ficheros generadas a partir de este fichero:
  IEParser.java
  IEParserTokenTypes.java
  IEParserTokenTypes.txt
*/

header {
  package ie;
}

class IEParser extends Parser;

options {
    buildAST = true;
    importVocab = IELexer;
    exportVocab = IEParser;
    ASTLabelType = "IEAST";
    defaultErrorHandler = false;
}

tokens {
  LIST;
}

{
  public static final String t2S(int i) {
    return _tokenNames[i];
  }
}

program
  :    
    global
    main
    (modules)*
    EOF!
    {##=#(#[LIST, "program"], ##) ; }
  ;

global
  :
    DDOT^ ID
    dec_know
  ;

main
  :
    DDOT^ ID
    mod_bloc
  ;

modules
  :
    DDOT^ ID
    mod_bloc
  ;

dec_know
  :
    ( knowD )*
    {##=#(#[LIST, "dec_know"], ##) ; }
  ;

mod_bloc
  :
    (term)*
    {##=#(#[LIST, "mod_bloc"], ##) ; }
  ;

term
  :
    (
      expr
        (   ASIG^ expr DOT!
          | MACRO^ expr DOT!
          | NORMAL^ ik DOT!
          | PERSISTENT^ ik DOT!
          | DDDOT^ type
        )
      | (
            PRINT^
          | ABORT^
        )
        ( exprs )? DOT!
    )
  ;

ik
  :
    ( know (COMMA! know)* ) ?
    {##=#(#[LIST, "list_knows"], ##) ; }
  ;

know
  :
    expr
      (   ASIG^ expr
        | MACRO^ expr
        | DDDOT^ type
      )
  | (
        PRINT^
      | ABORT^
    )
    ( exprs )?
  ;

knowD
  :
    expr
      (   ASIG^ expr DOT!
        | MACRO^ expr DOT!
        | DDDOT^ type
      )
  | (
        PRINT^
      | ABORT^
    )
    ( exprs )?
    DOT!
  ;

type:       typeB (APP^ type)?;
typeB:      OSB^ type CSB! | OCURLY^ type (COMMA! type)+ CCURLY! | ID | uni | OP! type CP!;

exprs:      expr | STRING;
expr:       expr2;
expr2:      expr3 (OR^ expr3)* ;
expr3:      expr4 (AND^ expr4)* ;
expr4:      exprC ((EQUAL^ | NOTEQUAL^ | LESSEQUAL^ | GREATEQUAL^ |
                    LESS^ | GREAT^) exprC)? ;
exprC:      expr5 ((PLUSPLUS^ | MINUSMINUS^) expr5)* ;
expr5:      expr6 ((PLUS^ | MINUS^) expr6)* ;
expr6:      expr8 ((MUL^ | DIV^ | REST^) expr8)* ;
expr8:      (NOT^ | MINUS^) expr8 | exprB ;
//exprA:      exprB (COMPOSITE^ exprB)* ;
exprB:      expr9 | SHARP^ expr9 ;
expr9:      expr11 (INDEX^ expr11)* ;
expr11:     ID^ (ID | expr12)* | expr12; 
expr12:     OP! expr CP!
            | INTCONST
            | REALCONST
            | tuple
            | list
            ;
/*
expr12:       OP! (
                    expr CP!            //poner auqí los diferentes ops?
                  | opers CP! (ID | expr12)*
                  )
            | INTCONST
            | REALCONST
            | tuple
            | list
            ;
*/
tuple:      OCURLY^ expr (COMMA! expr)+ CCURLY! ;
list:       OSB^ (expr (COMMA! expr)*)? CSB!;

uni: MUL | UNIF2;
